#include "ThrumasterPusher.h"
#include <QDebug>
#include "Utils.h"

ThrumasterPusher::ThrumasterPusher(QObject *parent)
    : QObject{parent}, isContinueReading(true)
{
    // 初始化 HIDAPI 库
    if (hid_init()) {
        qCritical() << "Failed to initialize HIDAPI library.";
    }

    // 枚举所有连接的 HID 设备
    struct hid_device_info *devs, *cur_dev;
    devs = hid_enumerate(0x0, 0x0);
    cur_dev = devs;

    // 遍历所有HID设备，找到生产商名为"Thustmaster"的设备，为推杆
    while (cur_dev) {
        qDebug() << QString::fromWCharArray(cur_dev->manufacturer_string);
        if (QString::fromWCharArray(cur_dev->manufacturer_string).contains("Thrustmaster")) {
            device = hid_open_path(cur_dev->path);
            break;
        }
        cur_dev = cur_dev->next;
    }

    hid_free_enumeration(devs);
}

ThrumasterPusher::~ThrumasterPusher()
{
    if (device) {
        hid_close(device);
    }
    hid_exit();
}

void ThrumasterPusher::readRawData() {
    // 读取摇杆数据
    if (device) {
        static unsigned char buf[65];

        // 读取一次数据
        int res = hid_read(device, buf, sizeof(buf));
        if (res > 0) {
            parseButtons(buf, res);
            parseSwitcher2s(buf, res);
            parseSwitcher3s(buf, res);
            parseAxis4(buf, res);
            parseAxis8(buf, res);
            parseSlider(buf, res);
            parseAxisSlider(buf, res);
            parsePushers(buf, res);
        }
    } else {
        qCritical() << "No Thustmaster pusher found.";
    }
}

void ThrumasterPusher::stopReadData()
{
    isContinueReading = false;
}


void ThrumasterPusher::parseButtons(unsigned char data[], int n)
{
    if(n > 5) {
        quint8 thirdByte = data[2], fourthByte = data[3], fifthByte = data[4];

        if((fifthByte & 0x02) >> 1)
            setButton1(ThrumasterPusher::Button_PUSHED);
        else
            setButton1(ThrumasterPusher::Button_RELEASE);

        if((fourthByte & 0x10) >> 4)
            setButton2(ThrumasterPusher::Button_PUSHED);
        else
            setButton2(ThrumasterPusher::Button_RELEASE);

        if((thirdByte & 0x40) >> 6)
            setButton3(ThrumasterPusher::Button_PUSHED);
        else
            setButton3(ThrumasterPusher::Button_RELEASE);
    }
}

void ThrumasterPusher::parseSwitcher2s(unsigned char data[], int n)
{
    if(n > 5) {
        quint8 thirdByte = data[2], fourthByte = data[3], fifthByte = data[4];

        if((fourthByte & 0x80) >> 7)
            setSwitcher21(ThrumasterPusher::Switcher2_ON);
        else
            setSwitcher21(ThrumasterPusher::Switcher2_OFF);

        if((fifthByte & 0x01) >> 0)
            setSwitcher22(ThrumasterPusher::Switcher2_ON);
        else
            setSwitcher22(ThrumasterPusher::Switcher2_OFF);

        if((fourthByte & 0x08) >> 3)
            setSwitcher23(ThrumasterPusher::Switcher2_ON);
        else
            setSwitcher23(ThrumasterPusher::Switcher2_OFF);

        if((thirdByte & 0x80) >> 7)
            setSwitcher24(ThrumasterPusher::Switcher2_ON);
        else
            setSwitcher24(ThrumasterPusher::Switcher2_OFF);

        if((fourthByte & 0x01) >> 0)
            setSwitcher25(ThrumasterPusher::Switcher2_ON);
        else
            setSwitcher25(ThrumasterPusher::Switcher2_OFF);
    }
}

void ThrumasterPusher::parseSwitcher3s(unsigned char data[], int n)
{
    if(n > 5) {
        quint8 secondByte = data[1], thirdByte = data[2], fourthByte = data[3], fifthByte = data[4];

        if((fifthByte & 0x04) >> 2)
            setSwitcher31(ThrumasterPusher::Switcher3_UP);
        else if((fifthByte & 0x08) >> 3)
            setSwitcher31(ThrumasterPusher::Switcher3_DOWN);
        else
            setSwitcher31(ThrumasterPusher::Switcher3_MID);

        if((fourthByte & 0x20) >> 5)
            setSwitcher32(ThrumasterPusher::Switcher3_UP);
        else if((fourthByte & 0x40) >> 6)
            setSwitcher32(ThrumasterPusher::Switcher3_DOWN);
        else
            setSwitcher32(ThrumasterPusher::Switcher3_MID);

        if((fifthByte & 0x80) >> 7)
            setSwitcher33(ThrumasterPusher::Switcher3_UP);
        else if((fourthByte & 0x04) >> 2)
            setSwitcher33(ThrumasterPusher::Switcher3_DOWN);
        else
            setSwitcher33(ThrumasterPusher::Switcher3_MID);

        if((fifthByte & 0x40) >> 6)
            setSwitcher34(ThrumasterPusher::Switcher3_UP);
        else if((fourthByte & 0x02) >> 1)
            setSwitcher34(ThrumasterPusher::Switcher3_DOWN);
        else
            setSwitcher34(ThrumasterPusher::Switcher3_MID);

        if((thirdByte & 0x10) >> 4)
            setSwitcher35(ThrumasterPusher::Switcher3_UP);
        else if((thirdByte & 0x20) >> 5)
            setSwitcher35(ThrumasterPusher::Switcher3_DOWN);
        else
            setSwitcher35(ThrumasterPusher::Switcher3_MID);

        if((secondByte & 0x40) >> 6)
            setSwitcher36(ThrumasterPusher::Switcher3_UP);
        else if((secondByte & 0x80) >> 7)
            setSwitcher36(ThrumasterPusher::Switcher3_DOWN);
        else
            setSwitcher36(ThrumasterPusher::Switcher3_MID);

        if((thirdByte & 0x01))
            setSwitcher37(ThrumasterPusher::Switcher3_UP);
        else if((thirdByte & 0x02) >> 1)
            setSwitcher37(ThrumasterPusher::Switcher3_DOWN);
        else
            setSwitcher37(ThrumasterPusher::Switcher3_MID);

        if((thirdByte & 0x04) >> 2)
            setSwitcher38(ThrumasterPusher::Switcher3_UP);
        else if((thirdByte & 0x08) >> 3)
            setSwitcher38(ThrumasterPusher::Switcher3_DOWN);
        else
            setSwitcher38(ThrumasterPusher::Switcher3_MID);
    }
}

void ThrumasterPusher::parseAxis4(unsigned char data[], int n)
{
    if(n > 2) {
        quint8 secondByte = data[1];

        switch (secondByte) {
        case 0x04:
            setAxis4(ThrumasterPusher::Axis_UP);
            break;
        case 0x10:
            setAxis4(ThrumasterPusher::Axis_DOWN);
            break;
        case 0x20:
            setAxis4(ThrumasterPusher::Axis_LEFT);
            break;
        case 0x08:
            setAxis4(ThrumasterPusher::Axis_RIGHT);
            break;
        default:
            setAxis4(ThrumasterPusher::Axis_RELEASE);
        }
    }
}

void ThrumasterPusher::parseAxis8(unsigned char data[], int n)
{
    if(n > 2) {
        quint8 sixthByte = data[5];

        switch (sixthByte) {
        case 0x44:
            setAxis8(ThrumasterPusher::Axis_UP);
            break;
        case 0x10:
            setAxis8(ThrumasterPusher::Axis_DOWN);
            break;
        case 0x86:
            setAxis8(ThrumasterPusher::Axis_LEFT);
            break;
        case 0x22:
            setAxis8(ThrumasterPusher::Axis_RIGHT);
            break;
        case 0xc5:
            setAxis8(ThrumasterPusher::Axis_LEFT_UP);
            break;
        case 0x97:
            setAxis8(ThrumasterPusher::Axis_LEFT_DOWN);
            break;
        case 0x63:
            setAxis8(ThrumasterPusher::Axis_RIGHT_UP);
            break;
        case 0x31:
            setAxis8(ThrumasterPusher::Axis_RIGHT_DOWN);
            break;
        case 0x0f:
            setAxis8(ThrumasterPusher::Axis_RELEASE);
        }
    }
}

void ThrumasterPusher::parseAxisSlider(unsigned char data[], int n)
{
    if(n > 10) {
        quint8 secondByte = data[1], seventhByte = data[6], eighthByte = data[7], ninthByte = data[8], tenthByte = data[9];

        if((secondByte & 0x01) >> 0)
            setAxisSliderPressed(true);
        else
            setAxisSliderPressed(false);

        int value1 = seventhByte + 0xff * eighthByte;
        int value2 = ninthByte + 0xff * tenthByte;
        int min = 0, max = 0xff * 4;
        setAxisSliderX(Utils::normalization(value1, max, min, 0.05));
        setAxisSliderY(Utils::normalization(value2, max, min, 0.05));
    }
}

void ThrumasterPusher::parseSlider(unsigned char data[], int n)
{
    if(n > 12) {
        quint8 eleventhByte = data[10], twelfthByte = data[11];

        int value = eleventhByte + 0xff * twelfthByte;
        int min = 0, max = 0xff * 4;
        setSlider(Utils::normalization(value, max, min, 0.01));
    }
}

void ThrumasterPusher::parsePushers(unsigned char data[], int n)
{
    if(n > 16) {
        quint8 thirteenthByte = data[12], fourteenthByte = data[13];
        quint8 fifteenthByte = data[14], sixteenthByte = data[15];

        int value1 = fifteenthByte + 0xff * sixteenthByte;
        int value2 = thirteenthByte + 0xff * fourteenthByte;
        int min = 0, max = 0xff * 0x40;
        setPusher1(Utils::normalization(value1, max, min, 0.05));
        setPusher2(Utils::normalization(value2, max, min, 0.05));
    }
}

ThrumasterPusher::ButtonState ThrumasterPusher::button1() const
{
    return m_button1;
}

void ThrumasterPusher::setButton1(ButtonState newButton1)
{
    if (m_button1 == newButton1)
        return;
    m_button1 = newButton1;
    emit button1Changed();
}

ThrumasterPusher::ButtonState ThrumasterPusher::button2() const
{
    return m_button2;
}

void ThrumasterPusher::setButton2(ButtonState newButton2)
{
    if (m_button2 == newButton2)
        return;
    m_button2 = newButton2;
    emit button2Changed();
}

ThrumasterPusher::ButtonState ThrumasterPusher::button3() const
{
    return m_button3;
}

void ThrumasterPusher::setButton3(ButtonState newButton3)
{
    if (m_button3 == newButton3)
        return;
    m_button3 = newButton3;
    emit button3Changed();
}

ThrumasterPusher::Switcher2State ThrumasterPusher::switcher21() const
{
    return m_switcher21;
}

void ThrumasterPusher::setSwitcher21(Switcher2State newSwitcher21)
{
    if (m_switcher21 == newSwitcher21)
        return;
    m_switcher21 = newSwitcher21;
    emit switcher21Changed();
}

ThrumasterPusher::Switcher2State ThrumasterPusher::switcher22() const
{
    return m_switcher22;
}

void ThrumasterPusher::setSwitcher22(Switcher2State newSwitcher22)
{
    if (m_switcher22 == newSwitcher22)
        return;
    m_switcher22 = newSwitcher22;
    emit switcher22Changed();
}

ThrumasterPusher::Switcher2State ThrumasterPusher::switcher23() const
{
    return m_switcher23;
}

void ThrumasterPusher::setSwitcher23(Switcher2State newSwitcher23)
{
    if (m_switcher23 == newSwitcher23)
        return;
    m_switcher23 = newSwitcher23;
    emit switcher23Changed();
}

ThrumasterPusher::Switcher2State ThrumasterPusher::switcher24() const
{
    return m_switcher24;
}

void ThrumasterPusher::setSwitcher24(Switcher2State newSwitcher24)
{
    if (m_switcher24 == newSwitcher24)
        return;
    m_switcher24 = newSwitcher24;
    emit switcher24Changed();
}

ThrumasterPusher::Switcher2State ThrumasterPusher::switcher25() const
{
    return m_switcher25;
}

void ThrumasterPusher::setSwitcher25(Switcher2State newSwitcher25)
{
    if (m_switcher25 == newSwitcher25)
        return;
    m_switcher25 = newSwitcher25;
    emit switcher25Changed();
}

ThrumasterPusher::Switcher3State ThrumasterPusher::switcher31() const
{
    return m_switcher31;
}

void ThrumasterPusher::setSwitcher31(Switcher3State newSwitcher31)
{
    if (m_switcher31 == newSwitcher31)
        return;
    m_switcher31 = newSwitcher31;
    emit switcher31Changed();
}

ThrumasterPusher::Switcher3State ThrumasterPusher::switcher32() const
{
    return m_switcher32;
}

void ThrumasterPusher::setSwitcher32(Switcher3State newSwitcher32)
{
    if (m_switcher32 == newSwitcher32)
        return;
    m_switcher32 = newSwitcher32;
    emit switcher32Changed();
}

ThrumasterPusher::Switcher3State ThrumasterPusher::switcher33() const
{
    return m_switcher33;
}

void ThrumasterPusher::setSwitcher33(Switcher3State newSwitcher33)
{
    if (m_switcher33 == newSwitcher33)
        return;
    m_switcher33 = newSwitcher33;
    emit switcher33Changed();
}

ThrumasterPusher::Switcher3State ThrumasterPusher::switcher34() const
{
    return m_switcher34;
}

void ThrumasterPusher::setSwitcher34(Switcher3State newSwitcher34)
{
    if (m_switcher34 == newSwitcher34)
        return;
    m_switcher34 = newSwitcher34;
    emit switcher34Changed();
}

ThrumasterPusher::Switcher3State ThrumasterPusher::switcher35() const
{
    return m_switcher35;
}

void ThrumasterPusher::setSwitcher35(Switcher3State newSwitcher35)
{
    if (m_switcher35 == newSwitcher35)
        return;
    m_switcher35 = newSwitcher35;
    emit switcher35Changed();
}

ThrumasterPusher::Switcher3State ThrumasterPusher::switcher36() const
{
    return m_switcher36;
}

void ThrumasterPusher::setSwitcher36(Switcher3State newSwitcher36)
{
    if (m_switcher36 == newSwitcher36)
        return;
    m_switcher36 = newSwitcher36;
    emit switcher36Changed();
}

ThrumasterPusher::Switcher3State ThrumasterPusher::switcher37() const
{
    return m_switcher37;
}

void ThrumasterPusher::setSwitcher37(Switcher3State newSwitcher37)
{
    if (m_switcher37 == newSwitcher37)
        return;
    m_switcher37 = newSwitcher37;
    emit switcher37Changed();
}

ThrumasterPusher::Switcher3State ThrumasterPusher::switcher38() const
{
    return m_switcher38;
}

void ThrumasterPusher::setSwitcher38(Switcher3State newSwitcher38)
{
    if (m_switcher38 == newSwitcher38)
        return;
    m_switcher38 = newSwitcher38;
    emit switcher38Changed();
}

ThrumasterPusher::AxisState ThrumasterPusher::axis8() const
{
    return m_axis8;
}

void ThrumasterPusher::setAxis8(AxisState newAxis8)
{
    if (m_axis8 == newAxis8)
        return;
    m_axis8 = newAxis8;
    emit axis8Changed();
}

double ThrumasterPusher::axisSliderX() const
{
    return m_axisSliderX;
}

void ThrumasterPusher::setAxisSliderX(double newAxisSliderX)
{
    if (qFuzzyCompare(m_axisSliderX, newAxisSliderX))
        return;
    m_axisSliderX = newAxisSliderX;
    emit axisSliderXChanged();
}

double ThrumasterPusher::axisSliderY() const
{
    return m_axisSliderY;
}

void ThrumasterPusher::setAxisSliderY(double newAxisSliderY)
{
    if (qFuzzyCompare(m_axisSliderY, newAxisSliderY))
        return;
    m_axisSliderY = newAxisSliderY;
    emit axisSliderYChanged();
}

ThrumasterPusher::AxisState ThrumasterPusher::axis4() const
{
    return m_axis4;
}

void ThrumasterPusher::setAxis4(AxisState newAxis42)
{
    if (m_axis4 == newAxis42)
        return;
    m_axis4 = newAxis42;
    emit axis4Changed();
}

bool ThrumasterPusher::axisSliderPressed() const
{
    return m_axisSliderPressed;
}

void ThrumasterPusher::setAxisSliderPressed(bool newAxisSliderPressed)
{
    if (m_axisSliderPressed == newAxisSliderPressed)
        return;
    m_axisSliderPressed = newAxisSliderPressed;
    emit axisSliderPressedChanged();
}

double ThrumasterPusher::slider() const
{
    return m_slider;
}

void ThrumasterPusher::setSlider(double newSlider)
{
    if (qFuzzyCompare(m_slider, newSlider))
        return;
    m_slider = newSlider;
    emit sliderChanged();
}

double ThrumasterPusher::pusher1() const
{
    return m_pusher1;
}

void ThrumasterPusher::setPusher1(double newPusher1)
{
    if (qFuzzyCompare(m_pusher1, newPusher1))
        return;
    m_pusher1 = newPusher1;
    emit pusher1Changed();
}

double ThrumasterPusher::pusher2() const
{
    return m_pusher2;
}

void ThrumasterPusher::setPusher2(double newPusher2)
{
    if (qFuzzyCompare(m_pusher2, newPusher2))
        return;
    m_pusher2 = newPusher2;
    emit pusher2Changed();
}
